#include "acl_stdafx.hpp"
#include "acl_cpp/stream/ostream.hpp"

namespace acl {

	int ostream::write(const void* data, size_t size, bool loop /* = true */)
	{
		int   ret;
		if (loop)
			ret = acl_vstream_writen(m_pStream, data, size);
		else
			ret = acl_vstream_write(m_pStream, data, (int) size);
		if (ret == ACL_VSTREAM_EOF)
			m_bEof = true;
		return (ret);
	}

	int ostream::writev(const struct iovec *v, int count, bool loop)
	{
		int   ret;
		if (loop)
			ret = acl_vstream_writevn(m_pStream, v, count);
		else
			ret = acl_vstream_writev(m_pStream, v, count);
		if (ret == ACL_VSTREAM_EOF)
			m_bEof = true;
		return (ret);
	}

	int ostream::vformat(const char* fmt, va_list ap)
	{
		int   ret = acl_vstream_vfprintf(m_pStream, fmt, ap);
		if (ret == ACL_VSTREAM_EOF)
			m_bEof = true;
		return (ret);
	}

	int ostream::write(acl_int64 n)
	{
		return (write(&n, sizeof(n), true));
	}

	int ostream::write(int n)
	{
		return (write(&n, sizeof(n), true));
	}

	int ostream::write(short n)
	{
		return (write(&n, sizeof(n), true));
	}

	int ostream::write(char ch)
	{
		return (write(&ch, sizeof(ch), false));
	}

	int ostream::write(const acl::string& s, bool loop)
	{
		return (write(s.c_str(), s.length(), loop));
	}

	int ostream::format(const char* fmt, ...)
	{
		va_list ap;

		va_start(ap, fmt);
		int ret = vformat(fmt, ap);
		va_end(ap);
		return (ret);
	}

	int ostream::puts(const char* s)
	{
		return (format("%s\r\n", s));
	}

	ostream& ostream::operator<<(const acl::string& s)
	{
		(void) write(s.c_str(), s.length(), true);
		return (*this);
	}

	ostream& ostream::operator<<(const char* s)
	{
		(void) write(s, strlen(s), true);
		return (*this);
	}

	ostream& ostream::operator<<(acl_int64 n)
	{
		(void) write(&n, sizeof(n), true);
		return (*this);
	}

	ostream& ostream::operator<<(int n)
	{
		(void) write(&n, sizeof(n), true);
		return (*this);
	}

	ostream& ostream::operator<<(short n)
	{
		(void) write(&n, sizeof(n), true);
		return (*this);
	}

	ostream& ostream::operator<<(char ch)
	{
		(void) write(&ch, sizeof(ch), false);
		return (*this);
	}

	int ostream::push_pop(const char* in, size_t len,
		string* out /* = NULL */ acl_unused,
		size_t max /* = 0 */ acl_unused)
	{
		if (in == NULL || len == 0)
			return (0);
		if ((size_t) write(in, len) != len)
			return (-1);
		if (out == NULL)
			return (0);
		if (max > 0 && len > max)
			len = max;
		out->append(in, len);
		return (len);
	}


} // namespace acl
